{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to atomman: Defect creation and analysis\n",
    "\n",
    "__Lucas M. Hale__, [lucas.hale@nist.gov](mailto:lucas.hale@nist.gov?Subject=ipr-demo), _Materials Science and Engineering Division, NIST_.\n",
    "    \n",
    "[Disclaimers](http://www.nist.gov/public_affairs/disclaimer.cfm) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Introduction<a id='section1'></a>\n",
    "\n",
    "One of the focuses of the atomman package is to provide tools for generating and analyzing atomic systems containing defects.  Many of these tools are more complex than the basic tools outlined in the previous section. This Notebook provides an overview of the various defect capabilities in atomman."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Library Imports**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "atomman version = 1.4.0\n",
      "Notebook executed on 2021-08-05\n"
     ]
    }
   ],
   "source": [
    "# Standard Python libraries\n",
    "import datetime\n",
    "\n",
    "# http://www.numpy.org/\n",
    "import numpy as np\n",
    "\n",
    "# https://github.com/usnistgov/atomman\n",
    "import atomman as am\n",
    "import atomman.unitconvert as uc\n",
    "\n",
    "# https://matplotlib.org/\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "# Show atomman version\n",
    "print('atomman version =', am.__version__)\n",
    "\n",
    "# Show date of Notebook execution\n",
    "print('Notebook executed on', datetime.date.today())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Point defects<a id='section2'></a>\n",
    "\n",
    "The atomman.defect.point() function inserts a point defect into a System and helps with tracking the defect by (1) moving any new/modified atoms to the end of the Atoms list and (2) adding per-atom property old_id that retains each atom's original index.\n",
    "\n",
    "See [4.1. Point defect generation Jupyter Notebook](4.1._Point_defect_generation.html) for more examples.\n",
    "\n",
    "- __system__ (*atomman.System*) the system to add the defect to.\n",
    "- __ptd_type__ (*str*) indicates which type of point defect to add.\n",
    "    - ='v' -- vacancy\n",
    "    - ='s' -- substitutional\n",
    "    - ='i' -- positional interstitial\n",
    "    - ='db' -- dumbbell interstitial\n",
    "- __atype__ (*int, optional*) atom type for defect atom ('i', 's', 'db' styles).\n",
    "- __pos__ (*array-like object, optional*) position for adding the defect atom (all styles).\n",
    "- __ptd_id__ (*int, optional*) atom id where defect is added.  Alternative to using pos ('v', 's', 'db' styles).\n",
    "- __db_vect__ (*array-like object, optional*) vector associated with the dumbbell interstitial ('db' style).\n",
    "- __scale__ (*bool, optional*) indicates if pos and db_vect are absolute (False) or box-relative (True). Default is False.\n",
    "- __atol__ (*float, optional*) absolute tolerance for position-based searching. Default is 1e-3 angstroms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    atype   pos[0]   pos[1]   pos[2]\n",
      "0       1  0.00000  0.00000  0.00000\n",
      "1       1  1.43325  1.43325  1.43325\n",
      "2       1  2.86650  0.00000  0.00000\n",
      "3       1  4.29975  1.43325  1.43325\n",
      "4       1  0.00000  2.86650  0.00000\n",
      "5       1  1.43325  4.29975  1.43325\n",
      "6       1  2.86650  2.86650  0.00000\n",
      "7       1  4.29975  4.29975  1.43325\n",
      "8       1  0.00000  0.00000  2.86650\n",
      "9       1  1.43325  1.43325  4.29975\n",
      "10      1  2.86650  0.00000  2.86650\n",
      "11      1  4.29975  1.43325  4.29975\n",
      "12      1  0.00000  2.86650  2.86650\n",
      "13      1  1.43325  4.29975  4.29975\n",
      "14      1  2.86650  2.86650  2.86650\n",
      "15      1  4.29975  4.29975  4.29975\n"
     ]
    }
   ],
   "source": [
    "# Define 2x2x2 bcc demonstration supercell\n",
    "a = uc.set_in_units(2.8665, 'angstrom')\n",
    "box = am.Box(a=a, b=a, c=a)\n",
    "atoms = am.Atoms(atype=1, pos=[[0.0,0.0,0.0], [0.5,0.5,0.5]])\n",
    "ucell = am.System(atoms=atoms, box=box, scale=True)\n",
    "system = ucell.supersize(2,2,2)\n",
    "print(system.atoms_df())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    atype   pos[0]   pos[1]   pos[2]  old_id\n",
      "0       1  0.00000  0.00000  0.00000       0\n",
      "1       1  1.43325  1.43325  1.43325       1\n",
      "2       1  2.86650  0.00000  0.00000       2\n",
      "3       1  4.29975  1.43325  1.43325       3\n",
      "4       1  0.00000  2.86650  0.00000       4\n",
      "5       1  2.86650  2.86650  0.00000       6\n",
      "6       1  4.29975  4.29975  1.43325       7\n",
      "7       1  0.00000  0.00000  2.86650       8\n",
      "8       1  1.43325  1.43325  4.29975       9\n",
      "9       1  2.86650  0.00000  2.86650      10\n",
      "10      1  4.29975  1.43325  4.29975      11\n",
      "11      1  0.00000  2.86650  2.86650      12\n",
      "12      1  1.43325  4.29975  4.29975      13\n",
      "13      1  2.86650  2.86650  2.86650      14\n",
      "14      1  4.29975  4.29975  4.29975      15\n",
      "15      1  1.13325  3.99975  1.13325       5\n",
      "16      1  1.73325  4.59975  1.73325      16\n"
     ]
    }
   ],
   "source": [
    "# Change atom 5 into <111> dumbbell interstitial pair\n",
    "defect_system = am.defect.point(system, 'db', ptd_id=5, db_vect=[0.3, 0.3, 0.3])\n",
    "print(defect_system.atoms_df())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Free surfaces<a id='section3'></a>\n",
    "\n",
    "Atomic configurations with a specific crystalline free surface can be generated with the FreeSurface class.  \n",
    "\n",
    "See the [4.2. Free surface generator Jupyter Notebook](4.2._Free_surface_generator.html) for the underlying theory and examples of the class being used."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Stacking faults<a id='section4'></a>\n",
    "\n",
    "The atomman.defect.StackingFault class provides methods for generating atomic configurations of generalized stacking faults that can be used to compute stacking fault energies.  You can generate either a single configuration, or a 1D array of configurations for a slip plane and direction, or a 2D map of configurations exploring the full gamma surface.\n",
    "\n",
    "See the [4.3. Stacking fault generator Jupyter Notebook](4.3._Stacking_fault_generator.html) for a description of the class and examples.\n",
    "\n",
    "The atomman.defect.GammaSurface class provides convenient methods for plotting and interpolating generalized stacking fault ($\\gamma$ surface) data.\n",
    "\n",
    "See the [4.5. Gamma surface plotting Jupyter Notebook](4.5._Gamma_surface_plotting.html) for a description of the class and examples."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Dislocations<a id='section5'></a>\n",
    "\n",
    "*Updated version 1.2.5:* Ability to solve isotropic solutions added.\n",
    "\n",
    "*Added version 1.3.4:* Dislocation class\n",
    "\n",
    "The atomman.defect.solve_volterra_dislocation() function generates an elasticity solution for a perfectly straight dislocation. The function returns either a Stroh object or a IsotropicVolterraDislocation object which has methods for obtaining position-based displacements and stress states, as well as energy-related parameters.  \n",
    "\n",
    "The atomman.defect.Dislocation class provides a convenient tool for constructing atomic configurations of dislocations based on the Volterra solutions. \n",
    "\n",
    "See [4.4. Dislocation solution and generator Jupyter Notebook](4.4._Dislocation_solution_and_generator.html) for more details about the Volterra solvers and the dislocation configuration generation methods.\n",
    "\n",
    "There are also a number of analysis tools for characterizing dislocations and other crystalline defects.\n",
    "\n",
    "- **atomman.defect.slip_vector()** calculates the slip vector for all atoms in a system.  This is a good tool for characterizing plastic deformation within a system that occurs between two points in time. \n",
    "- **atomman.defect.disregistry()** characterizes a dislocation's planar spreading by calculating the relative displacement of atoms between the atomic planes above and below the dislocation's slip plane. \n",
    "- **atomman.defect.DifferentialDisplacement** allows for dislocation cores to be characterized using the difference in the displacements between all pairs of neighbor atoms relative to a perfect crystal configuration.\n",
    "\n",
    "See the [4.6. Dislocation analysis tools Jupyter Notebook](4.6._Dislocation_analysis_tools.html) for the underlying theory and examples of the tools being used.\n",
    "\n",
    "The atomman.defect.SDVPN class allows for Semidiscrete variational Peierls-Nabarro dislocation models to be constructed based on supplied generalized stacking fault energy values.\n",
    "\n",
    "See the [4.7. Semidiscrete variational Peierls-Nabarro model Jupyter Notebook](4.7._Semidiscrete_variational_Peierls-Nabarro_model.html) for a description of the method and examples. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Strain class <a id='section6'></a>\n",
    "\n",
    "*Added version 1.3.7*\n",
    "\n",
    "The atomman.defect.Strain class provides a means of computing atomistic strain properties on a per-atom basis.  In performing the calculation, the reference \"zero strain\" configuration can be specified either as a System object or by specifying ideal lattice vectors on a per-atom basis.\n",
    "\n",
    "See the [4.8. Strain class Juptyer Notebook](4.8._Strain_class.html) for a description of the class and examples. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
